home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / t3_1 / risc_src.lha / risc_sources / comp / top / defs.t < prev    next >
Encoding:
Text File  |  1990-04-12  |  23.3 KB  |  713 lines

  1. (herald (orbit_top defs))
  2.  
  3. ;;; Copyright (c) 1985 Yale University
  4. ;;;     Authors: N Adams, R Kelsey, D Kranz, J Philbin, J Rees.
  5. ;;; This material was developed by the T Project at the Yale University Computer 
  6. ;;; Science Department.  Permission to copy this software, to redistribute it, 
  7. ;;; and to use it for any purpose is granted, subject to the following restric-
  8. ;;; tions and understandings.
  9. ;;; 1. Any copy made of this software must include this copyright notice in full.
  10. ;;; 2. Users of this software agree to make their best efforts (a) to return
  11. ;;;    to the T Project at Yale any improvements or extensions that they make,
  12. ;;;    so that these may be included in future releases; and (b) to inform
  13. ;;;    the T Project of noteworthy uses of this software.
  14. ;;; 3. All materials developed as a consequence of the use of this software
  15. ;;;    shall duly acknowledge such use, in accordance with the usual standards
  16. ;;;    of acknowledging credit in academic research.
  17. ;;; 4. Yale has made no warrantee or representation that the operation of
  18. ;;;    this software will be error-free, and Yale is under no obligation to
  19. ;;;    provide any services, by way of maintenance, update, or otherwise.
  20. ;;; 5. In conjunction with products arising from the use of this material,
  21. ;;;    there shall be no use of the name of the Yale University nor of any
  22. ;;;    adaptation thereof in any advertising, promotional, or sales literature
  23. ;;;    without prior written consent from Yale in each case.
  24. ;;;
  25.  
  26. ;;;  Structure definitions
  27. ;;;  Node creation; interconnect manipulation
  28.  
  29. ;;; Reckless (little type checking)
  30. ;;; Reclaims node and variable storage
  31.  
  32. ;;; VARIABLES
  33. ;;;===========================================================================
  34. ;;; Structures to represent variables.
  35.  
  36. (define-structure-type variable
  37.   name          ; Source code name for variable (temporary, for debugging only)
  38.   id            ; Unique numeric identifier
  39.   binder        ; LAMBDA node which binds this variable
  40.   definition    ; Support information for this variable
  41.   number        ; K: var = (NTH (LAMBDA-ALL-VARIABLES (VARIABLE-BINDER var)) K)
  42.   refs          ; List of leaf nodes n for which (REFERENCE-VARIABLE n) = var.
  43.   type          ; The type of the variable's value at point of binding
  44.   rep           ; Representation for variable's value
  45.   flag          ; Useful slot, used by shapes, COPY-NODE, NODE->VECTOR, etc.
  46.   flags         ; For various annotations, e.g. IGNORABLE
  47.   (((print self stream)
  48.     (format stream "#{Variable~_~S~_~A}"
  49.             (object-hash self)
  50.             self))
  51.    ((display self stream)        ; hack for ~A (?!)
  52.     (format stream "~S_~S"
  53.             (cond ((primop? (variable-name self))
  54.                    (identification (variable-name self)))
  55.                   (else
  56.                    (variable-name self))) 
  57.             (variable-id self)))))
  58.  
  59. (lset *variable-id* 0)
  60.  
  61. (define variable-pool
  62.         (make-pool 'variable-pool make-variable 20 variable?))
  63.  
  64. (define (create-variable name)
  65.   (let ((var (obtain-from-pool variable-pool)))
  66.     (set (variable-name       var) name)
  67.     (set (variable-id         var) *variable-id*)
  68.     (set (variable-binder     var) nil)
  69.     (set (variable-definition var) nil)
  70.     (set (variable-refs       var) '())
  71.     (set (variable-type       var) type/top)
  72.     (set (variable-rep        var) 'rep/pointer)       
  73.     (set (variable-flag       var) nil)
  74.     (set (variable-flags      var) '())
  75.     (set *variable-id* (fx+ 1 *variable-id*))
  76.     var))
  77.  
  78. (define (used? var)
  79.   (and var
  80.        (variable-refs var)))
  81.  
  82. ;;; NODES
  83. ;;;============================================================================
  84. ;;; There are three node types:
  85. ;;;  - LAMBDA
  86. ;;;  - CALL
  87. ;;;  - LEAF
  88. ;;; Calls have a nonzero number of children, lambda nodes have a single child,
  89. ;;; leaf node have none.
  90.  
  91. (define-structure-type node
  92.   variant           ; Node type, a predicate (e.g. LAMBDA-NODE?)
  93.   parent            ; Parent node
  94.   role              ; node == ((NODE-ROLE node) (NODE-PARENT node))
  95.   simplified?       ; True if it has already been simplified.
  96.   instructions
  97.   stuff-0           ; Variant components
  98.   stuff-1
  99.   stuff-2
  100.   stuff-3
  101.   stuff-4
  102.   stuff-5
  103.   (((print node stream)
  104.     (print-node (node-variant node) node stream))))
  105. ;   ((disclose node)
  106. ;    (express node))))           ; For PP, and for CRAWL's P command.
  107.  
  108. (define node-pool (make-pool 'node-pool
  109.                              (lambda ()
  110.                                (let ((new (make-node)))
  111.                                  (set (node-role new) '<new>)
  112.                                  new))
  113.                              30
  114.                              node?))
  115.  
  116. (lset *node-count* 0)
  117. (lset *node-return-count* 0)
  118.  
  119. ;;; EMPTY
  120. ;;;==========================================================================
  121. ;;; EMPTY is used to mark empty parent and child slots in nodes.
  122.  
  123. (define empty
  124.   (object nil ((print self stream) (writes stream "#{Empty}"))))
  125.  
  126. (define-integrable (empty? obj) (eq? obj empty))
  127.  
  128. (define *empty* empty) ; compatibility
  129.  
  130. (define (proclaim-empty probe)
  131.   (cond ((not (empty? probe))
  132.          (bug "not empty - ~S" probe))))
  133.  
  134. ;;; NODE VARIANTS
  135. ;;;==========================================================================
  136. ;;; A "node variant" is a predicate which answers true to nodes which
  137. ;;; belong to this variant node type.
  138.  
  139. (define-operation (print-node variant node stream))
  140.  
  141. (define (create-node-variant id)
  142.   (labels ((self
  143.             (object (lambda (obj)
  144.                       (eq? (node-variant obj) self))
  145.                     ((print self stream)
  146.                      (format stream "#{Node-variant~_~S}" id))
  147.                     ((print-node self node stream)
  148.                      (format stream "#{~S-node~_~S}" id (object-hash node))))))
  149.     self))
  150.  
  151. (define (create-node variant)
  152.   (let ((node (obtain-from-pool node-pool)))
  153.     (if (not (or (eq? '<erased> (node-role node))
  154.                  (eq? '<new> (node-role node))))
  155.         (bug "new node already in use ~S" node))
  156.     (set *node-count* (fx+ 1 *node-count*))
  157.     (set (node-variant      node) variant)
  158.     (set (node-parent       node) empty)
  159.     (set (node-role         node) '<free>)
  160.     (set (node-simplified?  node) nil)
  161.     (set (node-instructions node) '())
  162.     (set (node-stuff-0      node) nil)
  163.     (set (node-stuff-1      node) nil)
  164.     (set (node-stuff-2      node) nil)
  165.     (set (node-stuff-3      node) nil)
  166.     (set (node-stuff-4      node) nil)
  167.     (set (node-stuff-5      node) nil)
  168.     node))
  169.  
  170. (define (make-empty-node-list size)
  171.   (do ((i 0 (fx+ 1 i))
  172.        (l '() (cons-from-freelist empty l)))
  173.       ((fx>= i size) l)))
  174.  
  175. ;;; NODE FIELDS
  176. ;;;===========================================================================
  177. ;;;  These are used to rename the NODE-STUFF fields of particular node
  178. ;;; variants.
  179.  
  180. ;;; Ugh.  Done to get node fields integrable in the quick version.
  181. ;;; (define-local-syntax (node-field variant field id) field)
  182.  
  183. (define-constant (node-field variant field id)
  184.   (object (lambda (node)
  185.             (field (check-arg variant node id)))
  186.     ((setter self)
  187.      (lambda (node val)
  188.        (set (field (check-arg variant node id)) val)))
  189.     ((identification self) id)))
  190.  
  191. ;;; RELATIONS
  192. ;;;=========================================================================
  193. ;;; A "relation" is a selector procedure - something appropriate to put in
  194. ;;; the ROLE slot of a node.
  195.  
  196. (define (make-relation id variant slot)
  197.   (object (lambda (node)
  198.             (slot node))
  199.     ((setter self) (setter slot))
  200.     ((relation-variant self) variant)
  201.     ((print self stream)
  202.      (format stream "#{Relation~_~S}" id))))
  203.  
  204. (define (make-list-relation id variant slot index pred)
  205.   (object (lambda (node)
  206.             (nth (slot node) index))
  207.     ((setter self)
  208.      (lambda (node value) (set (nth (slot node) index) value)))
  209.     ((relation-index self) index)
  210.     ((relation-variant self) variant)
  211.     ((pred self) t)               ; hack
  212.     ((print self stream)
  213.      (format stream "#{Relation~_~S}" id))))
  214.  
  215. (define-operation (relation-variant relation))
  216. (define-operation (relation-index relation))
  217.  
  218. (define-integrable (relate relation parent child)
  219.   (proclaim-empty (node-parent child))  ; Could be flushed
  220.   (proclaim-empty (relation parent))    ; Could be flushed
  221.   (set (relation parent) child)
  222.   (set (node-parent child) parent)
  223.   (set (node-role child) relation))
  224.  
  225. (define (relate-list relations start parent list children)
  226.   (do ((i start (fx+ 1 i))
  227.        (l list (cdr l))
  228.        (children children (cdr children)))
  229.       ((null? children))
  230.     (let ((child (car children)))
  231.       (proclaim-empty (node-parent child))     ; Could be flushed
  232.       (proclaim-empty (car l))                 ; Could be flushed
  233.       (set (node-role child) (relations i))
  234.       (set (node-parent child) parent)
  235.       (set (car l) child))))
  236.  
  237. ;;; RECLAIMING NODES
  238. ;;;============================================================================
  239. ;;;     Erase node structure.  Updates the REFS slot of variables free to this
  240. ;;; node and returns the node to the pool.  There is some safety question
  241. ;;; here about erasing references to variables that have already been erased.
  242. ;;; I don't think it is a problem but it could be checked.
  243.  
  244. (define (erase node)
  245.   (cond ((empty? node)
  246.          nil)
  247.         (else
  248.          (cond ((eq? (node-role node) '<erased>)
  249.                 (bug "node erased twice ~S" node))
  250.                ((reference-node? node)
  251.                 (let ((var (reference-variable node)))
  252.                   (set (variable-refs var)
  253.                        (free-delq! node (variable-refs var)))))
  254.                ((lambda-node? node)
  255.                 (walk (lambda (v)
  256.                         (if v (return-to-pool variable-pool v)))
  257.                       (lambda-all-variables node))
  258.                 (return-list-to-freelist (lambda-all-variables node))
  259.                 (set (lambda-all-variables node) '())))
  260.          (set (node-role node) '<erased>)
  261.          (set *node-return-count* (fx+ 1 *node-return-count*))
  262.          (return-to-pool node-pool node))))
  263.  
  264. (define (erase-all node)
  265.   (iterate label ((node node))
  266.     (cond ((empty? node)
  267.            nil)
  268.           (else
  269.            (select (node-variant node)
  270.              ((lambda-node?)
  271.               (label (lambda-body node)))
  272.              ((call-node?)
  273.               (walk label (call-proc+args node))
  274.               (return-list-to-freelist (call-proc+args node)))
  275.              ((object-node?) 
  276.               (label (object-proc node))
  277.               (return-to-freelist (object-proc-pair node))
  278.               (walk label (object-operations node))
  279.               (return-list-to-freelist (object-operations node))
  280.               (walk label (object-methods node))
  281.               (return-list-to-freelist (object-methods node))))
  282.            (erase node)))))
  283.  
  284. ;;; CONNECTING AND DISCONNECTING NODES
  285. ;;;===========================================================================
  286.  
  287. ;;; Disconnect node from its parent.
  288.  
  289. (define-integrable (detach node)
  290.   (set ((node-role node) (node-parent node)) empty)
  291.   (set (node-role node) nil)
  292.   (set (node-parent node) empty)
  293.   node)
  294.  
  295. ;;; Replace node in tree with value of applying proc to node.
  296. ;;; Note the fact that a change has been made, for the simplifier.
  297.  
  298. (define (move node proc)
  299.   (let ((parent (node-parent node))
  300.         (role (node-role node)))
  301.     (mark-changed node)
  302.     (detach node)
  303.     (relate role parent (proc node))))
  304.  
  305. ;;; Add a new call into the node tree after lambda-node PARENT.
  306.  
  307. (define (insert-call call cont parent)
  308.   (move (lambda-body parent)
  309.         (lambda (old-body)
  310.           (relate lambda-body cont old-body)
  311.           call)))
  312.  
  313. ;;; Replace old-node with new-node.
  314. ;;; Note the fact that a change has been made, for the simplifier.
  315.  
  316. (define (replace old-node new-node)
  317.   (let ((role (node-role old-node))
  318.         (parent (node-parent old-node)))
  319.     (mark-changed old-node)
  320.     (set (node-parent old-node) empty)
  321.     (erase-all old-node)
  322.     (set (role parent) new-node)
  323.     (set (node-simplified? new-node) nil)
  324.     (set (node-parent new-node) parent)
  325.     (set (node-role new-node) role)))
  326.  
  327. (define (mark-changed node)
  328.   (do ((p (node-parent node) (node-parent p)))
  329.       ((or (empty? p)
  330.            (not (node-simplified? p))))
  331.     (set (node-simplified? p) nil)))
  332.  
  333. ;;; LEAF NODES
  334. ;;;=========================================================================
  335. ;;;   There are three kinds of leaf nodes - PRIMOP, LITERAL, REFERENCE
  336. ;;;
  337. ;;; Fields:
  338. ;;;   variant  - 'literal, 'primop, or 'reference
  339. ;;;   value    - Either a primop, a variable, or a literal value
  340. ;;;   type     - the type of the object this refers to (e.g. integer)
  341.  
  342. (define leaf-node? (create-node-variant 'leaf))
  343.  
  344. (define leaf-value
  345.   (node-field leaf-node? node-stuff-0 'leaf-value))
  346.  
  347. (define leaf-variant
  348.   (node-field leaf-node? node-stuff-1 'leaf-variant))
  349.  
  350. (define leaf-type
  351.   (node-field leaf-node? node-stuff-2 'leaf-type))
  352.  
  353. (define leaf-flags
  354.   (node-field leaf-node? node-stuff-3 'leaf-flag))
  355.  
  356. (define (create-leaf-node value variant)
  357.   (let ((node (create-node leaf-node?)))
  358.     (set (leaf-value   node) value)
  359.     (set (leaf-variant node) variant)
  360.     (set (leaf-type    node) nil)
  361.     node))
  362.  
  363. ;;; PRIMOP NODES
  364. ;;;=========================================================================
  365.  
  366. (define-integrable (create-primop-node primop)
  367.   (create-leaf-node primop 'primop))
  368.  
  369. (define-integrable (primop-node? node)
  370.   (and (leaf-node? node)
  371.        (eq? (leaf-variant node) 'primop)))
  372.  
  373. ;;; Checks to see if NODE is a reference to on of the primops in PRIMOPS.
  374. (define-integrable (primop-ref? node primop)
  375.   (and (primop-node? node)
  376.        (eq? (primop-value node) primop)))
  377.  
  378. (define-constant primop-value leaf-value)
  379.  
  380. ;;; LITERAL NODES
  381. ;;;=========================================================================
  382.  
  383. (define-integrable (create-literal-node value)
  384.   (create-leaf-node value 'literal))
  385.  
  386. (define-integrable (literal-node? node)
  387.   (and (leaf-node? node)
  388.        (eq? (leaf-variant node) 'literal)))
  389.  
  390. (define-constant literal-value leaf-value)
  391.   
  392. ;;; REFERENCE NODES
  393. ;;;=========================================================================
  394.  
  395. (define-integrable (create-reference-node variable)
  396.   (let ((node (create-leaf-node variable 'reference)))
  397.     (push (variable-refs variable) node)
  398.     node))
  399.  
  400. (define-integrable (reference-node? node)
  401.   (and (leaf-node? node)
  402.        (eq? (leaf-variant node) 'reference)))
  403.  
  404. (define-integrable (variable-ref? node . variables)
  405.   (and (reference-node? node)
  406.        (memq? (reference-variable node) variables)))
  407.  
  408. (define-constant reference-variable leaf-value)
  409.  
  410. (define-constant reference-flags leaf-flags)
  411.  
  412. ;;; LAMBDA NODES
  413. ;;;============================================================================
  414. ;;; Fields:
  415. ;;;   variables - list of variables which are bound by this lambda.  The first
  416. ;;;        variable gets bound to the procedure itself; the second is a 'rest'
  417. ;;;        variable, if it is non-null the lambda is n-ary.
  418. ;;;   body      - the node for the body (after CPS, always a call node)
  419. ;;;   env       - list of variables live on entry to this lambda
  420. ;;;   strategy  - label, stack, or heap (where are closures over this lambda?)
  421. ;;;   live      - the variables live in the body of the lambda.
  422. ;;;   db        - trace information.
  423.  
  424.  
  425. (define lambda-node? (create-node-variant 'lambda))
  426.  
  427. (define lambda-body
  428.   (make-relation 'lambda-body lambda-node? node-stuff-0))
  429.  
  430. (define lambda-all-variables
  431.   (node-field lambda-node? node-stuff-1 'lambda-all-variables))
  432.  
  433. (define lambda-env
  434.   (node-field lambda-node? node-stuff-2 'lambda-env))
  435.  
  436. (define lambda-strategy
  437.   (node-field lambda-node? node-stuff-3 'lambda-strategy))
  438.  
  439. (define lambda-live
  440.   (node-field lambda-node? node-stuff-4 'lambda-live))
  441.  
  442. (define lambda-db
  443.   (node-field lambda-node? node-stuff-5 'lambda-db))
  444.  
  445. ;;; Selecting various subsets of a lambda's variables.
  446.  
  447. (define-integrable (lambda-variables node)
  448.   (cddr (lambda-all-variables node)))
  449.  
  450. (define-integrable (lambda-rest+variables node)
  451.   (cdr (lambda-all-variables node)))
  452.  
  453. (define-integrable (lambda-self-var node)
  454.   (car (lambda-all-variables node)))
  455.  
  456. (define-integrable (lambda-rest-var node)
  457.   (cadr (lambda-all-variables node)))
  458.  
  459. (define-integrable (lambda-cont-var node)
  460.   (caddr (lambda-all-variables node)))
  461.  
  462. ;;;    Creates a lambda node.  NAME is used as the name of the lambda node's
  463. ;;; self variable.   VARS is a list of variables.  The VARIABLE-BINDER and
  464. ;;; VARIABLE-NUMBER slots of the variables are set.
  465.  
  466. (define (create-lambda-node name vars)
  467.   (let ((node (create-node lambda-node?))
  468.         (vars (cons-from-freelist (create-variable name)
  469.                                   vars)))
  470.     (set (lambda-all-variables node) vars)
  471.     (set (lambda-strategy      node) nil) 
  472.     (set (lambda-live          node) nil)
  473.     (set (lambda-env           node) nil)
  474.     (set (lambda-body          node) empty)
  475.     (do ((vars vars (cdr vars))
  476.          (n 0 (fx+ n 1)))
  477.         ((null? vars))
  478.       (let ((var (car vars)))
  479.         (cond (var
  480.                (set (variable-binder var) node)
  481.                (set (variable-number var) n)))))
  482.     node))
  483.  
  484. ;;; CALL NODES
  485. ;;;==========================================================================
  486. ;;; Fields:
  487. ;;;   exits      - the number of initial arguments that are continuations
  488. ;;;   complexity - no longer used...
  489. ;;;   hoisted-cont - continuation to be consed on stack
  490. ;;;   proc+args  - list of child nodes
  491.  
  492. (define call-node? (create-node-variant 'call))
  493.                                                        
  494. (define call-proc+args
  495.   (node-field call-node? node-stuff-0 'call-proc+args))
  496.  
  497. (define call-exits
  498.   (node-field call-node? node-stuff-1 'call-exits))
  499.  
  500. (define call-complexity
  501.   (node-field call-node? node-stuff-2 'call-complexity))
  502.  
  503. (define call-hoisted-cont
  504.   (node-field call-node? node-stuff-3 'call-hoisted-cont))
  505.  
  506. (define call-source
  507.   (node-field call-node? node-stuff-4 'call-source))
  508.  
  509. ;;; Selecting various subsets of the children of a call node.
  510.  
  511. (define-integrable (call-args node)
  512.   (cdr (call-proc+args node)))
  513.  
  514. (define-integrable (call-exit-args node)
  515.   (sublist (call-args node) 0 (call-exits node)))
  516.  
  517. (define-integrable (call-non-exit-args node)
  518.   (nthcdr (call-args node) (call-exits node)))
  519.  
  520. ;;;   T if NODE is an exit of a call node, NIL otherwise.
  521.  
  522. (define (call-exit? node)
  523.   (let ((role (node-role node)))
  524.     (cond ((not (call-arg? role))
  525.            nil)
  526.           ((lambda-node? (call-proc (node-parent node)))
  527.            (eq? role call-proc))
  528.           ((eq? role call-proc)
  529.            (fx= 0 (call-exits (node-parent node))))
  530.           (else
  531.            (fx<= (call-arg-number role)
  532.                  (call-exits (node-parent node)))))))
  533.  
  534. ;;; Create a call node with N children and EXITS exits.  Add new argument
  535. ;;; relations if their aren't enough.
  536.  
  537. (define (create-call-node n exits)
  538.   (let ((node (create-node call-node?)))
  539.     (set (call-proc+args node) (make-empty-node-list n))
  540.     (set (call-exits node) exits)
  541.     (set (call-complexity node) nil)
  542.     (set (call-hoisted-cont node) nil)
  543.     (set (call-source node) nil)
  544.     node))
  545.  
  546. ;;; ARGUMENT RELATIONS
  547. ;;;========================================================================
  548. ;;; Argument relations are created on demand whenever a newly created
  549. ;;; call node is going to have more arguments than any previous call node
  550. ;;; has had.
  551.  
  552. (define-predicate call-arg?)
  553.  
  554. (define (make-arg-relation i)
  555.   (make-list-relation `(call-arg ,i) call-node? call-proc+args i call-arg?))
  556.  
  557. (define-constant call-arg-number relation-index)
  558.  
  559. (define-constant call-proc 
  560.   (make-list-relation 'call-proc call-node? call-proc+args 0 call-arg?))
  561.  
  562. (define call-arg-relations
  563.   (make-infinite-vector 20 make-arg-relation 'call-arg-relations))
  564.  
  565. (set (call-arg-relations 0) call-proc)
  566.  
  567. (define-integrable (call-arg i)
  568.   (call-arg-relations i))
  569.  
  570. ;;; Make ARGS the arguments of call node PARENT.
  571.  
  572. (define (relate-call-args node args)
  573.   (relate-list call-arg-relations 1 node (cdr (call-proc+args node)) args))
  574.  
  575. ;;; Replace the arguments of call node NODE with NEW-ARGS.
  576.  
  577. (define (replace-call-args node new-args)
  578.   (walk (lambda (n)
  579.           (if (not (empty? n))
  580.               (erase (detach n))))
  581.         (call-args node))
  582.   (relate-new-call-args node new-args))
  583.  
  584. ;;; Replace the arguments of call node NODE with (possibly shorter) NEW-ARGS.
  585.  
  586. (define (relate-new-call-args node new-args)
  587.   (modify (cdr (call-proc+args node))
  588.           (lambda (l)
  589.             (let ((n (fx- (length l) (length new-args))))
  590.               (nthcdr l n))))        ; pairs lost...
  591.   (relate-call-args node new-args))
  592.  
  593. ; Avoiding n-ary procedures
  594.  
  595. (define (relate-two-call-args node a1 a2)
  596.   (let ((l (flist2 a1 a2 '())))
  597.     (relate-call-args node l)
  598.     (return-list-to-freelist l)))
  599.  
  600. (define (relate-three-call-args node a1 a2 a3)
  601.   (let ((l (flist3 a1 a2 a3 '())))
  602.     (relate-call-args node l)
  603.     (return-list-to-freelist l)))
  604.  
  605. (define (relate-four-call-args node a1 a2 a3 a4)
  606.   (let ((l (flist4 a1 a2 a3 a4 '())))
  607.     (relate-call-args node l)
  608.     (return-list-to-freelist l)))
  609.  
  610. (define (relate-five-call-args node a1 a2 a3 a4 a5)
  611.   (let ((l (flist5 a1 a2 a3 a4 a5 '())))
  612.     (relate-call-args node l)
  613.     (return-list-to-freelist l)))
  614.  
  615.  
  616. ;;; OBJECT NODES
  617. ;;;===========================================================================
  618. ;;;  NUMBER      unique number for this object, used by PP-CPS
  619. ;;;  PROC-PAIR   CAR is the procedure node, must be a pair for SIMPLIFY
  620. ;;;  OPERATIONS  list of operation nodes
  621. ;;;  METHODS     list of method nodes, these are all LAMBDAs
  622. ;;;  OPERATION?  T if this object is an operation
  623.  
  624. (define object-node? (create-node-variant 'object))
  625.  
  626. (define-constant object-number
  627.   (make-relation 'object-number object-node? node-stuff-0))
  628.  
  629. (define-constant object-proc-pair
  630.   (make-relation 'object-proc-pair object-node? node-stuff-1))
  631.  
  632. (define object-operations
  633.   (node-field object-node? node-stuff-2 'object-operations))
  634.  
  635. (define object-methods
  636.   (node-field object-node? node-stuff-3 'object-methods))
  637.  
  638. (define object-operation?
  639.   (node-field object-node? node-stuff-4 'object-operation?))
  640.  
  641. ;;; Object proc
  642.  
  643. (define object-proc
  644.   (make-list-relation 'object-proc object-node? object-proc-pair 0 nil))
  645.  
  646. ;;; Object operations
  647.  
  648. (define-predicate object-op?)
  649.  
  650. (define (make-op-relation i)
  651.   (make-list-relation
  652.      `(object-op ,i) object-node? object-operations i object-op?))
  653.  
  654. (define-constant object-op-number relation-index)
  655.  
  656. (define object-op-relations
  657.   (make-infinite-vector 20 make-op-relation 'object-op-relations))
  658.  
  659. (define-integrable (object-op i)
  660.   (object-op-relations i))
  661.  
  662. (define (relate-object-ops node ops)
  663.   (relate-list object-op-relations 0 node (object-operations node) ops))
  664.  
  665. ;;; Object methods
  666.  
  667. (define-predicate object-method?)
  668.  
  669. (define (make-method-relation i)
  670.   (make-list-relation
  671.      `(object-method ,i) object-node? object-methods i object-method?))
  672.  
  673. (define-constant object-method-number relation-index)
  674.  
  675. (define object-method-relations
  676.   (make-infinite-vector 20 make-method-relation 'object-method-relations))
  677.  
  678. (define-integrable (object-method i)
  679.   (object-method-relations i))
  680.  
  681. (define (relate-object-methods node methods)
  682.   (relate-list object-method-relations 0 node (object-methods node) methods))
  683.  
  684. (define (create-object-node operation? n)
  685.   (let ((node (create-node object-node?)))
  686.     (set (object-number     node) *variable-id*)
  687.     (set (object-proc-pair  node) (flist1 empty '()))
  688.     (set (object-operations node) (make-empty-node-list n))
  689.     (set (object-methods    node) (make-empty-node-list n))
  690.     (set (object-operation? node) operation?)
  691.     (set *variable-id* (fx+ 1 *variable-id*))
  692.     node))
  693.  
  694. (define (maybe-replace-object-with-proc node)
  695.   (cond ((object-node? node)
  696.          (let ((proc (object-proc node)))
  697.            (replace node proc)
  698.            proc))
  699.         (else node)))
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.